home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Mac OS / Multiprocessing 2.1v2 SDK / Sample Code / MPFileCopy1.0b1 / MoreIsBetterParts / MoreInterfaceLib / MoreInterfaceLib.c next >
Encoding:
Text File  |  1999-09-15  |  30.3 KB  |  812 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MoreInterfaceLib.c
  3.  
  4.     Contains:    Compatibility shim for routines not in InterfaceLib.
  5.  
  6.     Written by:    Quinn
  7.  
  8.     Copyright:    Copyright © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.  
  20.         <10>     16/9/99    Quinn   Add FSM FCB accessors.
  21.          <9>     16/8/99    Quinn   Added comment about nasty restriction with MorePBRemoteAccess.
  22.          <8>     22/7/99    Quinn   Use correct ProcInfo in MoreAddDrive.
  23.          <7>     15/6/99    Quinn   Added MoreBlockZero.
  24.          <6>     15/6/99    Quinn   Fixed Gestalt Value glue for pre-8.5 systems.  Added Extended
  25.                                     Disk Init Package routines.
  26.          <5>     22/4/99    Quinn   Added PBRemoteAccess.
  27.          <4>     20/4/99    Quinn   Added Gestalt Value routines.
  28.          <3>     16/3/99    Quinn   Added MoreUTFindDrive and MoreAddDrive.  Also fixed some mixups
  29.                                     about which traps are toolbox traps and which aren't.
  30.          <2>      1/3/99    Quinn   Added MoreFlushCodeCacheRange.  Also some general tidy up.
  31.          <1>     25/2/99    Quinn   First checked in.
  32. */
  33.  
  34. /////////////////////////////////////////////////////////////////
  35. // MoreIsBetter Setup
  36.  
  37. #include "MoreSetup.h"
  38.  
  39. /////////////////////////////////////////////////////////////////
  40. // Mac OS Interfaces
  41.  
  42. #include <CodeFragments.h>
  43. #include <LowMem.h>
  44. #include <Traps.h>
  45. #include <FSM.h>
  46. #include <Gestalt.h>
  47. #include <DiskInit.h>
  48.  
  49. /////////////////////////////////////////////////////////////////
  50. // Our Prototypes
  51.  
  52. #include "MoreInterfaceLib.h"
  53.  
  54. /////////////////////////////////////////////////////////////////
  55.  
  56. // This file contains implementations of various Mac OS API routines
  57. // that were rolled in to InterfaceLib as of Mac OS 8.5.  They are
  58. // in the InterfaceLib stub library as of Universal Interfaces 3.2.
  59. // This code does the magic to decide whether the routine is available
  60. // via InterfaceLib, or whether we have to synthesise our own MixedMode
  61. // glue (or, in some cases, implementation).
  62.  
  63. // If you use any of the routines in this library, you must either:
  64. //
  65. // a) continue to hard link to InterfaceLib, in which case you won't
  66. //    launch on pre-8.5 systems (with a cryptic error message), or
  67. // b) weak link to InterfaceLib, in which case you must check that you're
  68. //    on 8.5 or later before calling any of these routine lest
  69. //    you die by trying to call nil.
  70.  
  71. // You can change the definition of the following compiler variable,
  72. // which causes these routine to always use the InterfaceLib variant.
  73. // You'd better make sure they're available, as described above.
  74.  
  75. #ifndef MORE_MAC_OS_8_5_OR_LATER
  76.     #define MORE_MAC_OS_8_5_OR_LATER 0
  77. #endif
  78.  
  79. // Also, Universal Interfaces 3.2 defines macros for some missing
  80. // low memory accessors.  For CFM code, these macros override
  81. // the external procedure definition.  So you can no longer
  82. // call the real accessors, even if you do depend on Mac OS 8.5
  83. // or greater.  This hack fixes the problem.  [Radar ID 2308604]
  84.  
  85. #undef LMGetUnitTableEntryCount
  86. #undef LMSetUnitTableEntryCount
  87.  
  88. /////////////////////////////////////////////////////////////////
  89.  
  90. #if TARGET_RT_MAC_CFM
  91.  
  92. extern pascal SInt16 MoreLMGetUnitTableEntryCount(void)
  93. {
  94.     if (MORE_MAC_OS_8_5_OR_LATER || (LMGetUnitTableEntryCount != (void *) kUnresolvedCFragSymbolAddress)) {
  95.         return LMGetUnitTableEntryCount();
  96.     } else {
  97.         return *((SInt16 *) 0x01d2);
  98.     }
  99. }
  100.  
  101. extern pascal void   MoreLMSetUnitTableEntryCount(SInt16 value)
  102. {
  103.     if (MORE_MAC_OS_8_5_OR_LATER || (LMSetUnitTableEntryCount != (void *) kUnresolvedCFragSymbolAddress)) {
  104.         LMSetUnitTableEntryCount(value);
  105.     } else {
  106.         *((SInt16 *) 0x01d2) = value;
  107.     }
  108. }
  109.  
  110. #endif
  111.  
  112. /////////////////////////////////////////////////////////////////
  113. // Mixed Mode ProcInfo Helper
  114.  
  115. // Bit Numbers
  116. //
  117. //  3         2         1         0
  118. // 10987654321098765432109876543210
  119.  
  120. // Stack Based Layout
  121. //
  122. //                             cccc <- calling convention = kPascalStackBased (0), kCStackBased (1), kThinkCStackBased (5)
  123. //                           ss     <- result size
  124. //                         ss       <- stack parameter 1 size
  125. //                       ss         <- stack parameter 2 size
  126. //                     ss           <- stack parameter 3 size
  127. //                   ss             <- stack parameter 4 size
  128. //                 ss               <- stack parameter 5 size
  129. //               ss                 <- stack parameter 6 size
  130. //             ss                   <- stack parameter 7 size
  131. //           ss                     <- stack parameter 8 size
  132. //         ss                       <- stack parameter 9 size
  133. //       ss                         <- stack parameter 10 size
  134. //     ss                           <- stack parameter 11 size
  135. //   ss                             <- stack parameter 12 size
  136.  
  137. // Register Based Layout
  138. //
  139. //                             cccc <- calling convention = kRegisterBased (2)
  140. //                      rrrss       <- register result location and size
  141. //                 rrrss            <- register parameter 1 location and size
  142. //            rrrss                 <- register parameter 1 location and size
  143. //       rrrss                      <- register parameter 1 location and size
  144. //  rrrss                           <- register parameter 1 location and size
  145.  
  146. // Dispatched Stack Based Layout
  147. //
  148. //                             cccc <- calling convention = kD0DispatchedPascalStackBased (8), kD1DispatchedPascalStackBased (12), kD0DispatchedCStackBased (9), kStackDispatchedPascalStackBased (14)
  149. //                           ss     <- result size
  150. //                         ss       <- selector size
  151. //                       ss         <- stack parameter 1 size
  152. //                     ss           <- stack parameter 2 size
  153. //                   ss             <- stack parameter 3 size
  154. //                 ss               <- stack parameter 4 size
  155. //               ss                 <- stack parameter 5 size
  156. //             ss                   <- stack parameter 6 size
  157. //           ss                     <- stack parameter 7 size
  158. //         ss                       <- stack parameter 8 size
  159. //       ss                         <- stack parameter 9 size
  160. //     ss                           <- stack parameter 10 size
  161. //   ss                             <- stack parameter 11 size
  162.  
  163. // Special Case Layout
  164. //
  165. //                             cccc <- calling convention = kSpecialCase (15)
  166. //                       xxxxxx     <- special case selector (see "MixedMode.h")
  167.  
  168. // Values for "ss":
  169. //
  170. // 00 = kNoByteCode
  171. // 01 = kOneByteCode
  172. // 10 = kTwoByteCode
  173. // 11 = kFourByteCode
  174.  
  175. // Values for "rrr":
  176. //
  177. //
  178. // 000 = kRegisterD0
  179. // 001 = kRegisterD1
  180. // 010 = kRegisterD2
  181. // 011 = kRegisterD3
  182. // 100 = kRegisterA0
  183. // 101 = kRegisterA1
  184. // 110 = kRegisterA2
  185. // 111 = kRegisterA3
  186.  
  187. /////////////////////////////////////////////////////////////////
  188.  
  189. #if TARGET_RT_MAC_CFM
  190.  
  191. // DriverInstallReserveMem is a bit trickier to implement than the
  192. // previous two routines.  Basically we have get the address of the
  193. // _DriverInstall ($A03D) trap and then call it using
  194. // CallOSTrapUniversalProc.  There are a number of important things
  195. // to note here:
  196. //   a) We can just get the trap address and treat it as a UPP.
  197. //      The trap tables are defined to contain UPPs, either pointers
  198. //      to real 68K code, or pointers to a routine descriptor (if
  199. //      the trap is native or fat).
  200. //   b) We must use CallOSTrapUniversalProc, not CallUniversalProc.
  201. //      CallOSTrapUniversalProc automatically does a number of things 
  202. //      that are very critical for call OS traps.  See "IM:PowerPC
  203. //      System Software", p2-42 for a full description.
  204. //   c) When calling OS traps from PPC, it's important to get the
  205. //      ProcInfo right.  Specifically, all OS traps assume an
  206. //      implicit parameter of D1 as the first parameter.  After
  207. //      that, the parameters should be defined in the order that
  208. //      they are declared in the prototype.  If you fail to get
  209. //      the order right, or to put D1 first, your code will work,
  210. //      up until it encounters someone who has patched the OS trap
  211. //      with a native or fat patch.  Then strange things will happen,
  212. //      and you'll spend hours in MacsBug trying to figure it out.
  213.  
  214. // The trap number and ProcInfo description for DriverInstallReserveMem.
  215.  
  216. enum {
  217.     _DriverInstallReserveMem = 0x0A43D
  218. };
  219.  
  220. enum {
  221.     uppDriverInstallProcInfo = kRegisterBased
  222.         | REGISTER_RESULT_LOCATION(kRegisterD0)
  223.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  224.         | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long)))
  225.         | REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(DRVRHeaderPtr)))
  226.         | REGISTER_ROUTINE_PARAMETER(3, kRegisterD0, SIZE_CODE(sizeof(short)))
  227. };
  228.  
  229. // IMPORTANT: Previous versions of TradDriverLoaderLib defined parameter 1
  230. // as sizeof(short), not sizeof(long).  I fixed this based on information
  231. // I extracted from the official Apple version of this glue, in the 
  232. // InterfaceLib implementation on Mac OS 8.5.
  233.  
  234. extern pascal OSErr  MoreDriverInstallReserveMem(DRVRHeaderPtr drvrPtr, DriverRefNum refNum)
  235. {
  236.     if (MORE_MAC_OS_8_5_OR_LATER || (DriverInstallReserveMem != (void *) kUnresolvedCFragSymbolAddress)) {
  237.         return DriverInstallReserveMem(drvrPtr, refNum);
  238.     } else {
  239.         UniversalProcPtr trapAddress;
  240.         
  241.         // Check that I've got the ProcInfo correct.  This magic value
  242.         // was extracted from InterfaceLib on Mac OS 8.5.
  243.  
  244.         MoreAssert(uppDriverInstallProcInfo == 0x00533822);
  245.         
  246.         trapAddress = GetOSTrapAddress(_DriverInstallReserveMem);
  247.         return CallOSTrapUniversalProc(trapAddress, uppDriverInstallProcInfo, _DriverInstallReserveMem, drvrPtr, refNum);
  248.     }
  249. }
  250.  
  251. #endif
  252.  
  253. /////////////////////////////////////////////////////////////////
  254.  
  255. #if TARGET_RT_MAC_CFM
  256.  
  257. enum {
  258.     uppFlushCodeCacheRangeProcInfo = kRegisterBased |
  259.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  260.             REGISTER_RESULT_LOCATION(kRegisterD0) |
  261.             REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(long))) |
  262.             REGISTER_ROUTINE_PARAMETER(2, kRegisterD1, SIZE_CODE(sizeof(long))) |
  263.             REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(void *))) |
  264.             REGISTER_ROUTINE_PARAMETER(4, kRegisterA1, SIZE_CODE(sizeof(unsigned long)))
  265. };
  266.  
  267. extern pascal OSErr  MoreFlushCodeCacheRange(void *address, unsigned long count)
  268. {
  269.     if (MORE_MAC_OS_8_5_OR_LATER || (FlushCodeCacheRange != (void *) kUnresolvedCFragSymbolAddress)) {
  270.         return FlushCodeCacheRange(address, count);
  271.     } else {
  272.         UniversalProcPtr trapAddress;
  273.         
  274.         // Check that I've got the ProcInfo correct.  This magic value
  275.         // was extracted from InterfaceLib on Mac OS 8.5.
  276.  
  277.         MoreAssert(uppFlushCodeCacheRangeProcInfo == 0x5e671822);
  278.         
  279.         trapAddress = GetOSTrapAddress(_HWPriv);
  280.         return CallOSTrapUniversalProc(trapAddress, uppFlushCodeCacheRangeProcInfo, 9, _HWPriv, address, count);
  281.     }
  282. }
  283.  
  284. #endif
  285.  
  286. /////////////////////////////////////////////////////////////////
  287.  
  288. #if TARGET_RT_MAC_CFM
  289.  
  290. enum {
  291.     uppUTFindDriveProcInfo = kD0DispatchedPascalStackBased |
  292.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  293.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(long))) |
  294.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(SInt16))) |
  295.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DrvQElPtr *))),
  296.     uppUTLocateFCBProcInfo = kD0DispatchedPascalStackBased
  297.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  298.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  299.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  300.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long)))
  301.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StringPtr)))
  302.              | DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short*)))
  303.              | DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(FCBRecPtr*))),
  304.     uppUTLocateNextFCBProcInfo = kD0DispatchedPascalStackBased
  305.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  306.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  307.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  308.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned long)))
  309.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StringPtr)))
  310.              | DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short*)))
  311.              | DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(FCBRecPtr*))),
  312.     uppUTIndexFCBProcInfo = kD0DispatchedPascalStackBased
  313.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  314.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  315.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(VCBPtr)))
  316.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short*)))
  317.              | DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(FCBRecPtr*))),
  318.     uppUTResolveFCBProcInfo = kD0DispatchedPascalStackBased
  319.              | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  320.              | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
  321.              | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  322.              | DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(FCBRecPtr*)))
  323. };
  324.  
  325. extern pascal OSErr MoreUTFindDrive(SInt16 driveNum, DrvQElPtr *driveQElementPtr)
  326. {
  327.     #if !TARGET_CPU_68K
  328.         if (MORE_MAC_OS_8_5_OR_LATER || (UTFindDrive != (void *) kUnresolvedCFragSymbolAddress)) {
  329.             return UTFindDrive(driveNum, driveQElementPtr);
  330.         } else
  331.     #endif
  332.         {
  333.             UniversalProcPtr trapAddress;
  334.             
  335.             // Check that I've got the ProcInfo correct.  This magic value
  336.             // was extracted from InterfaceLib on Mac OS 8.5.
  337.  
  338.             MoreAssert(uppUTFindDriveProcInfo == 0x0EE8);
  339.             
  340.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  341.             return CallUniversalProc(trapAddress, uppUTFindDriveProcInfo, 15, driveNum, driveQElementPtr);
  342.         }
  343. }
  344.  
  345. extern pascal OSErr MoreUTLocateFCB(VCBPtr                 volCtrlBlockPtr,
  346.                                  unsigned long             fileNum,
  347.                                  StringPtr                 namePtr,
  348.                                  short *                fileRefNum,
  349.                                  FCBRecPtr *            fileCtrlBlockPtr)
  350. {
  351.     #if !TARGET_CPU_68K
  352.         if (MORE_MAC_OS_8_5_OR_LATER || (UTLocateFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  353.             return UTLocateFCB(volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  354.         } else
  355.     #endif
  356.         {
  357.             UniversalProcPtr trapAddress;
  358.             
  359.             // Check that I've got the ProcInfo correct.  This magic value
  360.             // was extracted from InterfaceLib on Mac OS 8.5.
  361.  
  362.             MoreAssert(uppUTLocateFCBProcInfo == 0x03FFE8);
  363.             
  364.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  365.             return CallUniversalProc(trapAddress, uppUTLocateFCBProcInfo, 2, volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  366.         }
  367. }
  368.  
  369. extern pascal OSErr MoreUTLocateNextFCB(VCBPtr             volCtrlBlockPtr,
  370.                                  unsigned long             fileNum,
  371.                                  StringPtr                 namePtr,
  372.                                  short *                fileRefNum,
  373.                                  FCBRecPtr *            fileCtrlBlockPtr)
  374. {
  375.     #if !TARGET_CPU_68K
  376.         if (MORE_MAC_OS_8_5_OR_LATER || (UTLocateNextFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  377.             return UTLocateNextFCB(volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  378.         } else
  379.     #endif
  380.         {
  381.             UniversalProcPtr trapAddress;
  382.             
  383.             // Check that I've got the ProcInfo correct.  This magic value
  384.             // was extracted from InterfaceLib on Mac OS 8.5.
  385.  
  386.             MoreAssert(uppUTLocateNextFCBProcInfo == 0x03FFE8);
  387.             
  388.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  389.             return CallUniversalProc(trapAddress, uppUTLocateNextFCBProcInfo, 3, volCtrlBlockPtr, fileNum, namePtr, fileRefNum, fileCtrlBlockPtr);
  390.         }
  391. }
  392.  
  393. extern pascal OSErr MoreUTIndexFCB(VCBPtr                 volCtrlBlockPtr,
  394.                                  short *                fileRefNum,
  395.                                  FCBRecPtr *            fileCtrlBlockPtr)
  396. {
  397.     #if !TARGET_CPU_68K
  398.         if (MORE_MAC_OS_8_5_OR_LATER || (UTIndexFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  399.             return UTIndexFCB(volCtrlBlockPtr, fileRefNum, fileCtrlBlockPtr);
  400.         } else
  401.     #endif
  402.         {
  403.             UniversalProcPtr trapAddress;
  404.             
  405.             // Check that I've got the ProcInfo correct.  This magic value
  406.             // was extracted from InterfaceLib on Mac OS 8.5.
  407.  
  408.             MoreAssert(uppUTIndexFCBProcInfo == 0x03FE8);
  409.             
  410.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  411.             return CallUniversalProc(trapAddress, uppUTIndexFCBProcInfo, 4, volCtrlBlockPtr, fileRefNum, fileCtrlBlockPtr);
  412.         }
  413. }
  414.  
  415. extern pascal OSErr MoreUTResolveFCB(short                 fileRefNum,
  416.                                  FCBRecPtr *            fileCtrlBlockPtr)
  417. {
  418.     #if !TARGET_CPU_68K
  419.         if (MORE_MAC_OS_8_5_OR_LATER || (UTResolveFCB != (void *) kUnresolvedCFragSymbolAddress)) {
  420.             return UTResolveFCB(fileRefNum, fileCtrlBlockPtr);
  421.         } else
  422.     #endif
  423.         {
  424.             UniversalProcPtr trapAddress;
  425.             
  426.             // Check that I've got the ProcInfo correct.  This magic value
  427.             // was extracted from InterfaceLib on Mac OS 8.5.
  428.  
  429.             MoreAssert(uppUTResolveFCBProcInfo == 0x0EE8);
  430.             
  431.             trapAddress = GetToolTrapAddress(_HFSUtilDispatch);
  432.             return CallUniversalProc(trapAddress, uppUTResolveFCBProcInfo, 5, fileRefNum, fileCtrlBlockPtr);
  433.         }
  434. }
  435.  
  436. #endif
  437.  
  438. /////////////////////////////////////////////////////////////////
  439.  
  440. #if TARGET_RT_MAC_CFM
  441.  
  442. enum {
  443.     uppAddDriveProcInfo = kRegisterBased |
  444.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  445.             REGISTER_RESULT_LOCATION(kRegisterD0) |
  446.             REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(short))) |
  447.             REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(DrvQElPtr))) |
  448.             REGISTER_ROUTINE_PARAMETER(3, kRegisterD0, SIZE_CODE(sizeof(long)))
  449. };
  450.  
  451. // Some comments about the ProcInfo value:
  452. //
  453. // o It's set to return a result even though the high-level glue doesn't.
  454. //   This is because the trap returns a result in D0.  We can safely ignored
  455. //   it from the C code.
  456. //
  457. // o The D1 parameter is listed as sizeof(short), not sizeof(long) which is
  458. //   the size used by most other OS traps.  The reason: I'm not sure.
  459. //   Come to think of it, sizeof(short) makes more sense to me because
  460. //   that's what trap words are.  Anyway, I'm just parroting what
  461. //   InterfaceLib 8.5 does; my specific goal is to make CFM patches to
  462. //   AddDrive work properly, which requires that we all use identical
  463. //   ProcInfo's.
  464. //
  465. // o Register D0 contains the drvrRefNum and drvNum parameters combined,
  466. //   with drvNum in the high word and drvrRefNum in the low word.
  467. //   Oh, those wacky 68K calling conventions (-:
  468.  
  469. extern pascal void MoreAddDrive(DriverRefNum drvrRefNum, SInt16 drvNum, DrvQElPtr qEl)
  470. {
  471.     UInt32 response;
  472.     
  473.     if ( MORE_MAC_OS_8_5_OR_LATER || ((Gestalt(gestaltSystemVersion, (SInt32 *) &response) == noErr) && (response >= 0x0850))) {
  474.         AddDrive(drvrRefNum, drvNum, qEl);
  475.     } else {
  476.         UniversalProcPtr trapAddress;
  477.  
  478.         // Prior to Mac OS 8.5, the InterfaceLib glue for AddDrive was
  479.         // messed up, so we have to roll our own.
  480.         
  481.         // Check that I've got the ProcInfo correct.  This magic value
  482.         // was extracted from InterfaceLib on Mac OS 8.5.
  483.  
  484.         MoreAssert(uppAddDriveProcInfo == 0x0733022);
  485.         
  486.         trapAddress = GetOSTrapAddress(_AddDrive);
  487.         (void) CallOSTrapUniversalProc(trapAddress, uppAddDriveProcInfo, _AddDrive, qEl, ( ((UInt32) drvNum) << 16) | (UInt16) drvrRefNum);
  488.     }
  489. }
  490.  
  491. #else
  492.  
  493. // Unlike most of these glue routines, the 68K version of AddDrive 
  494. // is implemented as link-in glue.  Thus there are no inlines in the
  495. // interface file.  We therefore have to implement this routine for
  496. // classic 68K, as a simple call through to the real routine.
  497.  
  498. extern pascal void MoreAddDrive(DriverRefNum drvrRefNum, SInt16 drvNum, DrvQElPtr qEl)
  499. {
  500.     AddDrive(drvrRefNum, drvNum, qEl);
  501. }
  502.  
  503. #endif
  504.  
  505. /////////////////////////////////////////////////////////////////
  506.  
  507. #if TARGET_RT_MAC_CFM
  508.  
  509. enum {
  510.     _GestaltValue = 0xABF1
  511. };
  512.  
  513. enum {
  514.     uppNewGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  515.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  516.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  517.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  518.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  519.     uppReplaceGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  520.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  521.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  522.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  523.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  524.     uppSetGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  525.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  526.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  527.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType))) |
  528.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))),
  529.     uppDeleteGestaltValueProcInfo = kD0DispatchedPascalStackBased |
  530.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  531.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  532.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(OSType)))
  533. };
  534.  
  535. // The glue I use here is especially cheesy.  In general, I try
  536. // to avoid using the pre-processor for generating bogus C syntax,
  537. // ie I only use #if where I could syntactically use if().  However,
  538. // in this case I've been forced to break my own rules.  The problem
  539. // is that NewGestaltValue etc are not present in Universal Interface's
  540. // 3.2 InterfaceLib for CFM-68K.  Why?  I don't know for sure, but it
  541. // could be because they are only available in the real InterfaceLib for
  542. // Mac OS 8.5 and higher, and that can't be run on 68K machines.  Anyway,
  543. // given that they're not available in InterfaceLib, you can't reference
  544. // the symbol in the CFM-68K build, which requires ugly preprocessor
  545. // stuff.  There may be a better way of doing this, but I'm pushed for
  546. // time right now.  I hope to revisit it eventually.
  547. // -- Quinn, 20 Apr 1999
  548.  
  549. extern pascal OSErr MoreNewGestaltValue(OSType selector, long newValue)
  550. {
  551.     #if !TARGET_CPU_68K
  552.         if (MORE_MAC_OS_8_5_OR_LATER || (NewGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  553.             return NewGestaltValue(selector, newValue);
  554.         } else
  555.     #endif
  556.         {
  557.             UniversalProcPtr trapAddress;
  558.             
  559.             // Check that I've got the ProcInfo correct.  This magic value
  560.             // was extracted from InterfaceLib on Mac OS 8.5.
  561.  
  562.             MoreAssert(uppNewGestaltValueProcInfo == 0x00000FA8);
  563.             
  564.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  565.             return CallUniversalProc(trapAddress, uppNewGestaltValueProcInfo, 0x0401, selector, newValue);
  566.         }
  567. }
  568.  
  569. extern pascal OSErr MoreReplaceGestaltValue(OSType selector, long replacementValue)
  570. {
  571.     #if !TARGET_CPU_68K
  572.         if (MORE_MAC_OS_8_5_OR_LATER || (ReplaceGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  573.             return ReplaceGestaltValue(selector, replacementValue);
  574.         } else
  575.     #endif
  576.         {
  577.             UniversalProcPtr trapAddress;
  578.             
  579.             // Check that I've got the ProcInfo correct.  This magic value
  580.             // was extracted from InterfaceLib on Mac OS 8.5.
  581.  
  582.             MoreAssert(uppReplaceGestaltValueProcInfo == 0x00000FA8);
  583.             
  584.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  585.             return CallUniversalProc(trapAddress, uppReplaceGestaltValueProcInfo, 0x0402, selector, replacementValue);
  586.         }
  587. }
  588.  
  589. extern pascal OSErr MoreSetGestaltValue(OSType selector, long newValue)        
  590. {
  591.     #if !TARGET_CPU_68K
  592.         if (MORE_MAC_OS_8_5_OR_LATER || (SetGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  593.             return SetGestaltValue(selector, newValue);
  594.         } else
  595.     #endif
  596.         {
  597.             UniversalProcPtr trapAddress;
  598.             
  599.             // Check that I've got the ProcInfo correct.  This magic value
  600.             // was extracted from InterfaceLib on Mac OS 8.5.
  601.  
  602.             MoreAssert(uppSetGestaltValueProcInfo == 0x00000FA8);
  603.             
  604.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  605.             return CallUniversalProc(trapAddress, uppSetGestaltValueProcInfo, 0x0404, selector, newValue);
  606.         }
  607. }
  608.  
  609. extern pascal OSErr MoreDeleteGestaltValue(OSType selector)
  610. {
  611.     #if !TARGET_CPU_68K
  612.         if (MORE_MAC_OS_8_5_OR_LATER || (DeleteGestaltValue != (void *) kUnresolvedCFragSymbolAddress)) {
  613.             return DeleteGestaltValue(selector);
  614.         } else
  615.     #endif
  616.         {
  617.             UniversalProcPtr trapAddress;
  618.             
  619.             // Check that I've got the ProcInfo correct.  This magic value
  620.             // was extracted from InterfaceLib on Mac OS 8.5.
  621.  
  622.             MoreAssert(uppDeleteGestaltValueProcInfo == 0x000003A8);
  623.             
  624.             trapAddress = GetToolboxTrapAddress(_GestaltValue);
  625.             return CallUniversalProc(trapAddress, uppDeleteGestaltValueProcInfo, 0x0203, selector);
  626.         }
  627. }
  628.  
  629. #endif
  630.  
  631. /////////////////////////////////////////////////////////////////
  632.  
  633. #if TARGET_RT_MAC_CFM
  634.  
  635. // Golly, this one is ugly.  In prior to ARA 3.0, this trap was
  636. // implemented by 68K code that used D0 as a selector.  But
  637. // with ARA 3.0, this trap is implemented by PowerPC code whose
  638. // ProcInfo doesn't include the D0 selector.  So, you can either
  639. // declare the ProcInfo to include the selector, and then you won't
  640. // work with ARA 3.0 and higher, or you can declare it without
  641. // the selector, in which case register D0 won't be set up
  642. // and you won't work with ARA < 3.0.  Nasty.
  643. //
  644. // The long term solution is to check the version number of ARA
  645. // and do the right thing for each version.  Alas, I don't have
  646. // time to code and test that solution.  So I'm sticking with
  647. // the ARA 3.x solution for the moment.
  648. //
  649. // Bletch!
  650. //
  651. // Quinn, 16 Aug 1999
  652.  
  653. enum {
  654.     _RemoteAccess = 0xAA5B
  655. };
  656.  
  657. enum {
  658.     uppPBRemoteAccessProcInfo = kPascalStackBased
  659.          | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  660.          | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(TPRemoteAccessParamBlock)))
  661.          | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))
  662. };
  663.  
  664. extern pascal OSErr MorePBRemoteAccess(TPRemoteAccessParamBlock paramBlock, Boolean async)
  665.     // There is still no InterfaceLib entry for PBRemoteAccess, so
  666.     // we always do the CallUniversalProc thing.
  667. {
  668.     UniversalProcPtr trapAddress;
  669.     
  670.     trapAddress = GetToolboxTrapAddress(_RemoteAccess);
  671.     return CallUniversalProc(trapAddress, uppPBRemoteAccessProcInfo, paramBlock, async);
  672. }
  673.  
  674. #endif
  675.  
  676. /////////////////////////////////////////////////////////////////
  677.  
  678. #if TARGET_RT_MAC_CFM
  679.  
  680. enum {
  681.     uppDIXFormatProcInfo = kStackDispatchedPascalStackBased |
  682.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  683.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  684.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  685.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean))) |
  686.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned long))) |
  687.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(unsigned long *))),
  688.     uppDIXZeroProcInfo = kStackDispatchedPascalStackBased |
  689.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  690.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  691.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  692.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ConstStr255Param))) |
  693.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short))) |
  694.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short))) |
  695.             DISPATCHED_STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(short))) |
  696.             DISPATCHED_STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(unsigned long))) |
  697.             DISPATCHED_STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void *))),
  698.     uppDIReformatProcInfo = kStackDispatchedPascalStackBased |
  699.             RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
  700.             DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(SIZE_CODE(sizeof(short))) |
  701.             DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
  702.             DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) |
  703.             DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ConstStr255Param))) |
  704.             DISPATCHED_STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ConstStr255Param)))
  705. };
  706.  
  707. // These routines use the same cheesy glue structure as the Gestalt Value
  708. // routines, for much the same reasons.  See the comment above MoreNewGestaltValue
  709. // for more details.
  710.  
  711. extern pascal OSErr MoreDIXFormat(     short                     drvNum,
  712.                                      Boolean                 fmtFlag,
  713.                                      unsigned long             fmtArg,
  714.                                      unsigned long *        actSize)
  715. {
  716.     #if !TARGET_CPU_68K
  717.         if (MORE_MAC_OS_8_5_OR_LATER || (DIXFormat != (void *) kUnresolvedCFragSymbolAddress)) {
  718.             return DIXFormat(drvNum, fmtFlag, fmtArg, actSize);
  719.         } else
  720.     #endif
  721.         {
  722.             UniversalProcPtr trapAddress;
  723.             
  724.             // Check that I've got the ProcInfo correct.  This magic value
  725.             // was extracted from InterfaceLib on Mac OS 8.5.
  726.  
  727.             MoreAssert(uppDIXFormatProcInfo == 0x0000F6AE);
  728.             
  729.             trapAddress = GetToolboxTrapAddress(_Pack2);
  730.             return CallUniversalProc(trapAddress, uppDIXFormatProcInfo, 0x000C, drvNum, fmtFlag, fmtArg, actSize);
  731.         }
  732. }
  733.  
  734. extern pascal OSErr MoreDIXZero(     short                     drvNum,
  735.                                      ConstStr255Param         volName,
  736.                                      short                     fsid,
  737.                                      short                     mediaStatus,
  738.                                      short                     volTypeSelector,
  739.                                      unsigned long             volSize,
  740.                                      void *                    extendedInfoPtr)
  741. {
  742.     #if !TARGET_CPU_68K
  743.         if (MORE_MAC_OS_8_5_OR_LATER || (DIXZero != (void *) kUnresolvedCFragSymbolAddress)) {
  744.             return DIXZero(drvNum, volName, fsid, mediaStatus, volTypeSelector, volSize, extendedInfoPtr);
  745.         } else
  746.     #endif
  747.         {
  748.             UniversalProcPtr trapAddress;
  749.             
  750.             // Check that I've got the ProcInfo correct.  This magic value
  751.             // was extracted from InterfaceLib on Mac OS 8.5.
  752.  
  753.             MoreAssert(uppDIXZeroProcInfo == 0x003EAEAE);
  754.             
  755.             trapAddress = GetToolboxTrapAddress(_Pack2);
  756.             return CallUniversalProc(trapAddress, uppDIXZeroProcInfo, 0x000E, drvNum, volName, fsid, mediaStatus, volTypeSelector, volSize, extendedInfoPtr);
  757.         }
  758. }
  759.  
  760.  
  761. extern pascal OSErr MoreDIReformat(     short                     drvNum,
  762.                                      short                     fsid,
  763.                                      ConstStr255Param         volName,
  764.                                      ConstStr255Param         msgText)
  765. {
  766.     #if !TARGET_CPU_68K
  767.         if (MORE_MAC_OS_8_5_OR_LATER || (DIReformat != (void *) kUnresolvedCFragSymbolAddress)) {
  768.             return DIReformat(drvNum, fsid, volName, msgText);
  769.         } else
  770.     #endif
  771.         {
  772.             UniversalProcPtr trapAddress;
  773.             
  774.             // Check that I've got the ProcInfo correct.  This magic value
  775.             // was extracted from InterfaceLib on Mac OS 8.5.
  776.  
  777.             MoreAssert(uppDIReformatProcInfo == 0x0000FAAE);
  778.             
  779.             trapAddress = GetToolboxTrapAddress(_Pack2);
  780.             return CallUniversalProc(trapAddress, uppDIReformatProcInfo, 0x0010, drvNum, fsid, volName, msgText);
  781.         }
  782. }
  783.  
  784. #endif
  785.  
  786. /////////////////////////////////////////////////////////////////
  787.  
  788. // the routine uses the same cheesy glue structure as the Gestalt Value
  789. // routines, for much the same reasons.  See the comment above MoreNewGestaltValue
  790. // for more details.
  791.  
  792. extern pascal void MoreBlockZero(void * destPtr, Size byteCount)
  793. {
  794.     #if TARGET_RT_MAC_CFM && !TARGET_CPU_68K
  795.         if (MORE_MAC_OS_8_5_OR_LATER || (BlockZero != (void *) kUnresolvedCFragSymbolAddress)) {
  796.             BlockZero(destPtr, byteCount);
  797.         } else 
  798.     #endif
  799.         {
  800.             UInt8 *cursor;
  801.             
  802.             cursor = (UInt8 *) destPtr;
  803.             while (byteCount != 0) {
  804.                 *cursor = 0;
  805.                 cursor += 1;
  806.                 byteCount -= 1;
  807.             }
  808.         }
  809. }
  810.  
  811. /////////////////////////////////////////////////////////////////
  812.